﻿using Gds.Model.DataEnum;
using Gds.Model.TestFunctionModel;
using Gds.Utility.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using Gds.Model.ConfigModel.Controller;
using System.Net.NetworkInformation;
using System.Net.Mail;
using Gds.ViewModel.pageViewModel;
using System.Reflection;
using System.Runtime.Remoting.Messaging;

namespace Gds.TaskFunction.TestFunction
{
    /// <summary>
    /// 主站通讯方法
    /// </summary>
    public class ServerTestFcuntion : ITestFunction, IDisposable
    {
        bool _disposeFlag = false;
        public void Dispose()
        {
            PublicFunctionTool.AddLog("结束");
            _disposeFlag = true;
        }
        /// <summary>
        /// 开始全部控制器任务
        /// </summary>
        public void StartTask()
        {
            PublicFunctionTool.AddLog("开始通讯");
            _disposeFlag = false;
            ViewModel.pageViewModel.MainViewModel.Instance.DicTaskStation = new Dictionary<int, TaskStartModel>();
            ViewModel.pageViewModel.CommunicationLogViewModel.Instance.CurrentRunStateModels = new Model.AsyncObservableCollection<TaskRunStateModel>();
            #region  测试通讯流程方法
            //for (int i = 0; i < 10; i++)
            //{
            //    Task.Factory.StartNew(() =>
            //    {
            //        PublicFunctionTool.AddLog("线程" + (i + 1).ToString() + "启动");
            //        ViewModel.pageViewModel.MainViewModel.Instance.DicTaskStation.Add(i, new TaskStartModel()
            //        {
            //            TaskIndex = i,
            //            TaskStattion = true
            //        });
            //        testTaskFunction(null);
            //    });
            //    Thread.Sleep(1000);
            //}
            #endregion
            #region 实际使用方法
            foreach (var k in ViewModel.pageViewModel.MainViewModel.Instance.TaskStartModels)
            {
                CommunicationLogViewModel.Instance.CurrentRunStateModels.Add(new TaskRunStateModel()
                {
                    TaskIndex = k.TotalLineNo,
                    
                });
            }
            if(MainViewModel.Instance.LocalConfig.IsClientModel)
            {
                Task.Factory.StartNew(() =>
                {
                    LoopSpeckVoice();
                }, TaskCreationOptions.LongRunning);
            }
            foreach (var k in ViewModel.pageViewModel.MainViewModel.Instance.TaskStartModels)
            {
                if (k.TotalLineNo == 0) continue;
                if (k.Dic_Controller == null || k.Dic_Controller.Count == 0)
                {
                    continue;
                }
                bool isContinue = false;
                if(MainViewModel.Instance.LocalConfig.IsClientModel)
                {
                    foreach (var cp in ClientConfigVm.Instance.ClientModels)
                    {
                        if (int.Parse(cp.ServerTotalLine) == k.TotalLineNo)
                        {
                            isContinue = !cp.IsOpen;
        

                            break;
                        }
                    }
                }
                if (isContinue)
                {
                    PublicFunctionTool.AddLog("工控机 跳过" + k.TaskIndex.ToString() + "线程");

                    continue;
                }
                Task.Factory.StartNew(() =>
                {
                    PublicFunctionTool.AddLog("线程" + k.TaskIndex.ToString() + "启动");
                  
                    //气体系统后台软件
                    ViewModel.pageViewModel.MainViewModel.Instance.DicTaskStation.Add(k.TaskIndex, new TaskStartModel()
                    {
                        TaskIndex = k.TaskIndex,
                        TaskStattion = true
                    });
                    testTaskFunction(k);
                });
                Thread.Sleep(200);
            }
            #endregion 
        }
        /// <summary>
        /// 单个总线通讯方法
        /// </summary>
        /// <param name="taskModel"></param>
        public void testTaskFunction(TaskStartModel taskModel)
        {
            try
            {
                #region 流程
                //每一个线程关联一个串口
                //1.获取该串口关联的控制器
                //2.循环读取每个控制器数据
                //  2.1 查看是否需要消音复位
                //  2.2 读取控制器浓度信息
                //  2.3 根据控制器关联的探头信息，给对应的探头赋值，并且更新实时数据表， 以及保存探头历史数据
                //  2.4 判定探头是否告警，如果告警，则保存告警记录
                //3.结束该次循环通讯
                #endregion
                bool isAllUnUse = true;
                //不通讯控制器
                List<int> UnUseControllerList = new List<int>();
                Dictionary<int, Model.ConfigModel.CommuEquip.IcommuTool> dicCommuTool = new Dictionary<int, Model.ConfigModel.CommuEquip.IcommuTool>();

                //判断当前总线的所有探头是否都是屏蔽，是则不通讯
                foreach (var k in taskModel.Dic_Controller)
                {
                    foreach (var w in k.Value.Dic_GasMeter)
                    {
                        if (w.Value.IsUse == false)
                        {
                            isAllUnUse = false;

                            break;
                        }
                    }
                    if (isAllUnUse == true)
                    {
                        UnUseControllerList.Add(k.Value.Address);
                    }
                    isAllUnUse = true;
                }
                if (UnUseControllerList.Count != 0)
                {
                    foreach (var k in taskModel.Dic_Controller)
                    {
                        if (UnUseControllerList.Contains(k.Value.Address))
                        {
                            PublicFunctionTool.AddLog("总线" + taskModel.TotalLineNo + "-控制器" + k.Value.Address + " 全部探头都为屏蔽状态，不通讯");

                            ShowMsg("更新实时数据表， 以及保存探头历史数据", taskModel.TotalLineNo, k.Value.Address);
                            if (dicCommuTool.ContainsKey(k.Value.Address) == false)
                            {
                                dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_hnht());
                                dicCommuTool[k.Value.Address].realTimeValue = new Dictionary<int, Model.ConfigModel.GasMeter.GasSaveModel>();
                                foreach (var w in k.Value.Dic_GasMeter)
                                {
                                    dicCommuTool[k.Value.Address].realTimeValue.Add(w.Value.ChannelIndex, new Model.ConfigModel.GasMeter.GasSaveModel()
                                    {
                                        GasState = "备用",
                                        GasCurrentState = "备用",
                                        GasValue = "0",
                                        OccurTime = DateTime.Now,
                                    });


                                }
                            }
                            //保存屏蔽状态控制器
                            saveGasValue(dicCommuTool[k.Value.Address], k.Value.Dic_GasMeter);
                        }

                    }


                }
                SerialHelper serialHelper = new SerialHelper();
                if(MainViewModel.Instance.LocalConfig.IsClientModel)
                {
                    var clientPort = "COM";
                    foreach(var cp in ClientConfigVm.Instance.ClientModels)
                    {
                        if(int.Parse(cp.ServerTotalLine)== taskModel.TotalLineNo)
                        {
                            clientPort += cp.ClientPort;
                            break;
                        }
                    }
                    serialHelper.Port = clientPort;
                }
                else
                {

                    serialHelper.Port = taskModel.SerialPortCom;
                }
                
                serialHelper.Baudrate = taskModel.Baud;
                serialHelper.AnalyzeType = "Hex";
                serialHelper.WaitTime = taskModel.WaitTime;
                serialHelper.OpenPort();
                CommunicationLogViewModel.Instance.CurrentRunStateModels[taskModel.TaskIndex - 1].IsRun = true;
                int readSplit = int.Parse(ServerConfigViewModel.Instance.LocalConfig.ReadSplit);
                MainViewModel.Instance.ReadSplit = int.Parse(ServerConfigViewModel.Instance.LocalConfig.ReadSplit);
                while (true)
                {
                    CommunicationLogViewModel.Instance.CurrentRunStateModels[taskModel.TaskIndex - 1].StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                    readSplit =
            MainViewModel.Instance.ReadSplit;
                    // PublicFunctionTool.AddLog("线程" + taskIndex.ToString() + "Running");
                    foreach (var k in taskModel.Dic_Controller)
                    {
                        if (UnUseControllerList.Contains(k.Value.Address)) continue;
                        //2-初始化对应的工具类
                        if (dicCommuTool.ContainsKey(k.Value.Address) == false)
                        {
                            switch (k.Value.Factory)
                            {
                                case "化能汇通":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_hnht());
                                    dicCommuTool[k.Value.Address].IsCanSet = true;

                                    break;
                                case "4~20mA转485":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_4To20());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "ES2000_D系列":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_ES2000_D());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "FMC_1000PLUS":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_FMC_1000PLUS());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "SP_1003Plus":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_SP_10003Plus());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "ES2000":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_ES2000());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "无锡科士特GM系列":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_GMserial());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                case "鑫豪斯电子":
                                    dicCommuTool.Add(k.Value.Address, new Model.ConfigModel.CommuEquip.CommuTool_Xhs());
                                    dicCommuTool[k.Value.Address].IsCanSet = false;
                                    break;
                                default:
                                    Console.WriteLine("没有此款通讯协议");
                                    break;

                            }
                            dicCommuTool[k.Value.Address].TotalLineNumber = taskModel.TotalLineNo.ToString();
                            dicCommuTool[k.Value.Address].AddLogEventHandler += ServerTestFcuntion_AddLogEventHandler;
                            dicCommuTool[k.Value.Address].AddErrorLogEventHandler += ServerTestFcuntion_AddErrorLogEventHandler;
                            dicCommuTool[k.Value.Address].AddRunStateModelEventHandler += ServerTestFcuntion_AddRunStateModelEventHandler;
                            
                            dicCommuTool[k.Value.Address].SerialHelper = serialHelper;
                            dicCommuTool[k.Value.Address].MainAddress = k.Value.Address.ToString();
                            dicCommuTool[k.Value.Address].ControllerFailMaxTime = 5;

                        }
                        //  2.1 查看是否需要消音复位
                        ShowMsg("查看是否需要消音复位", taskModel.TotalLineNo, k.Value.Address);
                        checkResetOrNoVoice(dicCommuTool[k.Value.Address], taskModel.TotalLineNo, k.Value);
                        //  2.2 读取控制器浓度信息
                        ShowMsg("读取控制器浓度信息", taskModel.TotalLineNo, k.Value.Address);

                        //readPotencyFaker(dicCommuTool[k.Value.Address], k.Value);//模拟测试浓度的时候用
                        readPotency(dicCommuTool[k.Value.Address], k.Value);
                        //  2.3 根据控制器关联的探头信息，给对应的探头赋值，并且更新实时数据表， 以及保存探头历史数据

                        ShowMsg("检查是否显示数据", taskModel.TotalLineNo, k.Value.Address);
                        makeRealTimeModel(dicCommuTool[k.Value.Address].realTimeValue, k.Value.Dic_GasMeter, taskModel.TotalLineNo, k.Value.Address);
                        //  2.4更新实时数据表， 以及保存探头历史数据 
                        ShowMsg("更新实时数据表， 以及保存探头历史数据", taskModel.TotalLineNo, k.Value.Address);
                        saveGasValue(dicCommuTool[k.Value.Address], k.Value.Dic_GasMeter);
                        ShowMsg("数据保存完毕", taskModel.TotalLineNo, k.Value.Address);

                        Thread.Sleep(readSplit);
                        var SpeakModel = Utility.Helper.DataBaseHelper.FindOneModel<Gds.Model.ConfigModel.ClientConfig .RemoteControlModel>("RemoteControlModel");
                        //AddLogModel("读取RemoteControlModel 状态为" + SpeakModel.IsVoiceOpen.ToString());
                        System.Threading.Thread.Sleep(2000);
                       IsVoiceOpen = SpeakModel.IsVoiceOpen;
                    }

                    if (_disposeFlag)
                    {
                        ViewModel.pageViewModel.MainViewModel.Instance.DicTaskStation[taskModel.TaskIndex].TaskStattion = false;
                        PublicFunctionTool.AddLog("线程" + taskModel.TaskIndex.ToString() + "退出");
                        break;
                    }
                    Thread.Sleep(readSplit);
                    CommunicationLogViewModel.Instance.CurrentRunStateModels[taskModel.TaskIndex - 1].EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                }
                dicCommuTool = null;
                serialHelper.ClosePort();
                CommunicationLogViewModel.Instance.CurrentRunStateModels[taskModel.TaskIndex - 1].IsRun = false;
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }
            finally
            {
                ViewModel.pageViewModel.MainViewModel.Instance.DicTaskStation[taskModel.TaskIndex].TaskStattion = false;
                PublicFunctionTool.AddLog("线程" + taskModel.TaskIndex.ToString() + "退出");
            }


        }

        private void ServerTestFcuntion_AddRunStateModelEventHandler(object sender, EventArgs e)
        {
            List<string> listmsg = new List<string>();
            listmsg = sender as List<string>;

            foreach (var k in CommunicationLogViewModel.Instance.CurrentRunStateModels)
            {
                if (k.TaskIndex == int.Parse(listmsg[0]))
                { 
                    k.CurrentReadPotencyStep = listmsg[1];
                    if (listmsg[1].Contains("回复为空"))
                    {
                        k.EmptyRespondTime++;
                    }
                    if (listmsg[1].Contains("需要增加通讯等待时间"))
                    {
                        k.NeedMoreRespondTime++;
                    }
                    break;
                }
            }
           
           
        }

        private void SetRunStateMsg(int _index, string _message)
        {
            foreach (var k in CommunicationLogViewModel.Instance.CurrentRunStateModels)
            {
                if (k.TaskIndex == _index)
                { 
                k.CurrentStep= _message;
                    break;
                }
            }
            //CommunicationLogViewModel.Instance.CurrentRunStateModels[_index - 1].CurrentStep = _message;

        }
        private void ServerTestFcuntion_AddErrorLogEventHandler(object sender, EventArgs e)
        {
            ViewModel.pageViewModel.MainViewModel.Instance.AddLogModel(sender.ToString());
        }

        /// <summary>
        /// 触发显示日志事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void ServerTestFcuntion_AddLogEventHandler(object sender, EventArgs e)
        {
            List<string> list = new List<string>();
            list = sender as List<string>;
            ViewModel.pageViewModel.CommunicationLogViewModel.Instance.AddLogModel(list[0], int.Parse(list[1]), int.Parse(list[2]));
        }


        /// <summary>
        /// 判断控制器是否需要消音复位
        /// </summary>
        private void checkResetOrNoVoice(Model.ConfigModel.CommuEquip.IcommuTool _commuTool, int _totalLine, TaskControllerModel _controller)
        {
            if (_commuTool.IsCanSet == false) return;
                _controller.keyList = new List<object>();
            _controller.valueList = new List<object>();
            _controller.CurRemoteControllerModel = new ObservableCollection<Model.ConfigModel.RemoteControl.ControllermotivationModel>();
            _controller.keyList.Clear();
            _controller.valueList.Clear();

            _controller.keyList.Add("ControllerId");
            _controller.valueList.Add(_controller.Address);
            //1.读取数据消音复位数据
            _controller.CurRemoteControllerModel = DataBaseHelper.FindModelCol<Gds.Model.ConfigModel.RemoteControl.ControllermotivationModel>("ControllerMotivation", _controller.keyList, _controller.valueList);
            //2.判定是否需要操作
            foreach (var k in _controller.CurRemoteControllerModel)
            {
                bool isRun = false;
                    if (k.ControllerId == _controller.Address)//&& k.TotalLine == _totalLine
                    {
                    if(_commuTool.realTimeValue!=null)
                    {
                        foreach (var w in _commuTool.realTimeValue)
                        {
                            if (w.Value.GasState == "故障") continue;
                            if (w.Value.GasState != "正常")
                            {
                                isRun=true;
                                break;
                            }
                        }
                    }
                         if (isRun == false) break;
                        bool controllerResult = false;
                        if (k.NoVoiceFlag)//需要消音
                        {
                            ShowControlMsg("检查到总线[" + _totalLine + "]-控制器[" + _controller.Address + "]，需要消音");
                            controllerResult = _commuTool.Set_GasMeterNoVoice(_controller);
                            ShowControlMsg("检查到总线[" + _totalLine + "]-控制器[" + _controller.Address + "]，消音" + (controllerResult ? "成功" : "失败"));

                            //需要将状态置换
                            _controller.selectKey = new List<object>();
                            _controller.selectValue = new List<object>();
                            _controller.updateKey = new List<object>();
                            _controller.updateValue = new List<object>();
                            _controller.selectKey.Add("ControllerId");
                            _controller.selectValue.Add(_controller.Address);

                            _controller.updateKey.Add("NoVoiceFlag");
                            _controller.updateValue.Add(false);
                            Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.RemoteControl.ControllermotivationModel>("ControllerMotivation", _controller.selectKey, _controller.selectValue, _controller.updateKey, _controller.updateValue);
                        }
                        if (k.ResetFlag)//需要复位
                        {
                            ShowControlMsg("检查到总线[" + _totalLine + "]-控制器[" + _controller.Address + "]，需要复位");

                            controllerResult = _commuTool.Set_GasMeterReSet(_controller);
                            ShowControlMsg("检查到总线[" + _totalLine + "]-控制器[" + _controller.Address + "]，复位" + (controllerResult ? "成功" : "失败"));

                            //需要将状态置换
                            _controller.selectKey = new List<object>();
                            _controller.selectValue = new List<object>();
                            _controller.updateKey = new List<object>();
                            _controller.updateValue = new List<object>();
                            _controller.selectKey.Add("ControllerId");
                            _controller.selectValue.Add(_controller.Address);

                            _controller.updateKey.Add("ResetFlag");
                            _controller.updateValue.Add(false);
                            Utility.Helper.DataBaseHelper.UpDateModel<Model.ConfigModel.RemoteControl.ControllermotivationModel>("ControllerMotivation", _controller.selectKey, _controller.selectValue, _controller.updateKey, _controller.updateValue);

                        }
                        break;
                    }
                
                
            }

        }
        /// <summary>
        /// 读取探头浓度
        /// </summary>
        private void readPotency(Model.ConfigModel.CommuEquip.IcommuTool _commuTool, TaskControllerModel _controller)
        {
            _commuTool.ReadControllerData(_controller);
        }
        /// <summary>
        /// 读取探头浓度 模拟调试
        /// </summary>
        private void readPotencyFaker(Model.ConfigModel.CommuEquip.IcommuTool _commuTool, TaskControllerModel _controller)
        {
            _commuTool.realTimeValue = new Dictionary<int, Model.ConfigModel.GasMeter.GasSaveModel>();
            foreach (var k in _controller.Dic_GasMeter)
            {
                if (k.Value.IsUse == false)
                {
                    if (k.Value.SerialNo == "QT-KF-01")
                    {
                        _commuTool.realTimeValue.Add(k.Value.ChannelIndex, new Model.ConfigModel.GasMeter.GasSaveModel()
                        {
                            GasValue = "27.0",
                            GasState = "高高报"
                        });
                        //GasValue = "27.0",
                        //    GasState = "高高报"
                    }
                    else
                    {
                        _commuTool.realTimeValue.Add(k.Value.ChannelIndex, new Model.ConfigModel.GasMeter.GasSaveModel()
                        {
                            GasValue = "20.0",
                            GasState = "正常"
                        });
                    }
              
                }
                else

                {
                    _commuTool.realTimeValue.Add(k.Value.ChannelIndex, new Model.ConfigModel.GasMeter.GasSaveModel()
                    {
                        GasValue = "0.00",
                        GasState = "正常"
                    });
                }
              
            }
        }
        /// <summary>
        /// 赋值数据到实时数据模型
        /// </summary>
        private void makeRealTimeModel(Dictionary<int, Model.ConfigModel.GasMeter.GasSaveModel> realTimeData, Dictionary<int, Model.ConfigModel.GasMeter.TaskGasMeterModel> meterConfigDic, int totalLine, int Controller)
        {
            if (totalLine == MainViewModel.Instance.ShowLogControllerTotalLine && MainViewModel.Instance.IsShowCommunication && MainViewModel.Instance.ShowLogControllerAddressIndex == Controller)
            {
                int channalIndex = 1;
                foreach (var k in realTimeData)
                {
                    bool containFlag = false;
                    foreach (var w in CommunicationLogViewModel.Instance.GasMeterRealTimeDatas)
                    {
                        if (w.ChannalNo == channalIndex.ToString())
                        {
                            containFlag = true;
                            w.GasValue = k.Value.GasValue;
                            w.GasState = k.Value.GasState;
                            break;
                        }

                    }
                    if (containFlag == false)
                    {
                        CommunicationLogViewModel.Instance.GasMeterRealTimeDatas.Add(new Model.ConfigModel.GasMeter.ShowRealTimeModel()
                        {
                            ChannalNo = channalIndex.ToString(),
                            SerialNo = meterConfigDic[channalIndex].SerialNo,
                            GasValue = k.Value.GasValue,
                            GasState = k.Value.GasState,
                        });
                    }
                    channalIndex++;

                }

            }
        }
        /// <summary>
        /// 保存数据
        /// </summary>
        private void saveGasValue(Model.ConfigModel.CommuEquip.IcommuTool _commuTool, Dictionary<int, Model.ConfigModel.GasMeter.TaskGasMeterModel> _dicGasConfig)
        {
            try
            {
                if (_commuTool.realTimeValue != null)
                {
                    foreach (var k in _commuTool.realTimeValue)
                    {
                        if (_dicGasConfig[k.Key].IsUse == true) continue;//屏蔽探头不处理
                        //更新实时数据
                        if (MainViewModel.Instance.RealTimeGasPotencyModels.ContainsKey(_dicGasConfig[k.Key].SerialNo))
                        {
                            if (MainViewModel.Instance.RealTimeGasPotencyModels[_dicGasConfig[k.Key].SerialNo].GasValue != k.Value.GasValue || MainViewModel.Instance.RealTimeGasPotencyModels[_dicGasConfig[k.Key].SerialNo].GasState != k.Value.GasState)
                            {
                                ShowMsg("更新[" + _dicGasConfig[k.Key].SerialNo + "]实时数据", int.Parse(_commuTool.TotalLineNumber), int.Parse(_commuTool.MainAddress));
                                PublicFunctionTool.UpDateRealTimePotencyData(_dicGasConfig[k.Key].SerialNo, k.Value.GasValue, k.Value.GasState, k.Value.GasState);
                                MainViewModel.Instance.RealTimeGasPotencyModels[_dicGasConfig[k.Key].SerialNo].GasValue = k.Value.GasValue;
                                MainViewModel.Instance.RealTimeGasPotencyModels[_dicGasConfig[k.Key].SerialNo].GasState = k.Value.GasState;
                            }
                            else
                            {
                                ShowMsg("[" + _dicGasConfig[k.Key].SerialNo + "]实时数据,没有变化，不更新", int.Parse(_commuTool.TotalLineNumber), int.Parse(_commuTool.MainAddress));

                            }
                        }
                        else
                        {
                            ShowMsg("更新[" + _dicGasConfig[k.Key].SerialNo + "]实时数据", int.Parse(_commuTool.TotalLineNumber), int.Parse(_commuTool.MainAddress));
                            PublicFunctionTool.UpDateRealTimePotencyData(_dicGasConfig[k.Key].SerialNo, k.Value.GasValue, k.Value.GasState, k.Value.GasState);
                            MainViewModel.Instance.RealTimeGasPotencyModels.Add(_dicGasConfig[k.Key].SerialNo, new Model.ConfigModel.RealTimeModel.RealTimeGasPotencyModel()
                            {
                                GasSerialNo = _dicGasConfig[k.Key].SerialNo,
                                GasState = k.Value.GasState,
                                GasValue = k.Value.GasValue,
                            });
                        }
                        //插入该探头自己的数据表
                        DataBaseHelper.InserOneModel(k.Value, _dicGasConfig[k.Key].SerialNo);
                        //  2.4 判定探头是否告警，如果告警，则保存告警记录
                        ShowMsg("[" + _dicGasConfig[k.Key].SerialNo + "]检查是否告警", int.Parse(_commuTool.TotalLineNumber), int.Parse(_commuTool.MainAddress));
                        if(checkIsAlarm(k.Value, _dicGasConfig[k.Key]))
                        {
                            if(AlarmMeterList==null)
                            {
                                AlarmMeterList = new Queue<string>();
                            }
                            AlarmMeterList.Enqueue(string.Format("{0}、{1}报警、浓度{2}", _dicGasConfig[k.Key].Area, _dicGasConfig[k.Key].SerialNo, k.Value.GasValue));
                        }
                        ShowMsg("[" + _dicGasConfig[k.Key].SerialNo + "]检查告警完毕", int.Parse(_commuTool.TotalLineNumber), int.Parse(_commuTool.MainAddress));

                    }
                }
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }


        }
        #region 判断告警
        //Dictionary<string, Model.ConfigModel.GasMeter.AlarmSearchModel> dicGasState = new Dictionary<string, Model.ConfigModel.GasMeter.AlarmSearchModel>();
        Model.ConfigModel.GasMeter.AlarmSearchModel saveAlarmModel;
        int AlarmTotalCount = 0;
        bool isSaveAlarm = false;
        double alarmPotency = 0;
        double lastalarmPotency = 0;
        /// <summary>
        /// 检查是否告警
        /// </summary>
        private bool checkIsAlarm(Model.ConfigModel.GasMeter.GasSaveModel _saveModel, Model.ConfigModel.GasMeter.TaskGasMeterModel _configModel)
        {
            if (ViewModel.pageViewModel.MainViewModel.Instance.DicGasState == null) MainViewModel.Instance.DicGasState = new Dictionary<string, Model.ConfigModel.GasMeter.AlarmSearchModel>();
            //1.对比上一次的状态，来决定是更新记录 还是插入记录
            if (MainViewModel.Instance.DicGasState.ContainsKey(_configModel.SerialNo) == false)
            {
                //不存在上一次数据
                //1.1 状态正常
                if (_saveModel.GasState == "正常")
                {
                    return false;
                }
                else
                {
                    if (AlarmTotalCount == 0)
                    {
                        AlarmTotalCount = (int)DataBaseHelper.FindCollectionCount("GasMeterAlarmData");
                    }
                    //1.2判断当前浓度是否处于告警值内
                    isSaveAlarm = false;
                    if (_saveModel.GasState == "故障")
                    {
                        isSaveAlarm = true;
                    }
                    else
                    {
                        if (_configModel.GasType == "O2")
                        {
                            if (double.TryParse(_saveModel.GasValue, out alarmPotency))
                            {
                                //氧气判断是不是大于告警，或者小于低警
                                if (alarmPotency < _configModel.LowAlarmValue || alarmPotency > _configModel.HighAlarmValue)
                                {
                                    isSaveAlarm = true;
                                }
                            }
                        }
                        else
                        {
                            if (double.TryParse(_saveModel.GasValue, out alarmPotency))
                            {
                                //高于低警值 则保存
                                if (alarmPotency > _configModel.LowAlarmValue)
                                {
                                    isSaveAlarm = true;
                                }
                            }
                        }
                    }
                    if (isSaveAlarm)
                    {
                        //1.3 状态异常
                        //插入新纪录
                        _insertNewAlarmModel(_saveModel, _configModel);
                    }

                }


            }
            else
            {
                //已经记录的状态

                isSaveAlarm = false;
                if (AlarmTotalCount == 0)
                {
                    AlarmTotalCount = (int)DataBaseHelper.FindCollectionCount("GasMeterAlarmData");
                }
                if (MainViewModel.Instance.DicGasState[_configModel.SerialNo].GasStatu == changeStateStr(_saveModel.GasState))//状态一致
                {
                    //1.正常
                    if (_saveModel.GasState == "正常")
                    {
                        //跳过
                        isSaveAlarm = false;
                    }
                    else if (_saveModel.GasState == "故障")
                    {
                        //2.故障
                        //更新持续时间
                        _configModel.saveAlarmModel = upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true);
                        isSaveAlarm = true;
                    }
                    else
                    {
                        //3.告警
                        //更新持续时间，更新最大浓度
                        _configModel.saveAlarmModel = upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true, true);
                        isSaveAlarm = true;
                    }
                    if (isSaveAlarm)
                    {
                        MainViewModel.Instance.DicGasState[_configModel.SerialNo] = _configModel.saveAlarmModel;
                    }
                }
                else//状态不一致
                {
                    if (_saveModel.GasState == "正常")
                    {
                        //1.恢复正常
                        //更新结束时间
                        _configModel.saveAlarmModel = upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true, true, true);
                        MainViewModel.Instance.DicGasState[_configModel.SerialNo] = _configModel.saveAlarmModel;
                        _insertNewAlarmModel(_saveModel, _configModel);
                    }
                    else if (_saveModel.GasState == "故障")
                    {
                        //3.变成故障
                        if (MainViewModel.Instance.DicGasState[_configModel.SerialNo].GasStatu == "正常")
                        {

                        }
                        else
                        {
                            upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true, true, true);
                        }
                        //插入故障纪录
                        _insertNewAlarmModel(_saveModel, _configModel);
                    }
                    else//告警
                    {
                        //①正常=》告警
                        //②高低报 切换

                        //2.告警
                        //2.1氧气两级报警
                        //插入新纪录
                        //2.2单向告警 取告警状态
                        //更新状态，更新持续时间，，更新最大浓度
                        if (MainViewModel.Instance.DicGasState[_configModel.SerialNo].GasStatu == "正常")
                        {
                            //正常探头 不更新浓度
                            upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true, false, true);

                        }
                        else
                        { 
                        upgradeModel(MainViewModel.Instance.DicGasState[_configModel.SerialNo], _saveModel, _configModel, true, true, true);

                        }

                        //插入新告警纪录
                        _insertNewAlarmModel(_saveModel, _configModel);
                    }


                }
            }
            //saveAlarmModel = null;
            return true;
        }
        private string changeStateStr(string oldState)
        {
            string result = oldState;
            if (MainViewModel.Instance.LocalConfig.IsChangeStateStr)
            {
                if (result == "低警")
                {
                    result = MainViewModel.Instance.LocalConfig.LowAlarmStr;
                }
                else if (result == "高警")
                {
                    result = MainViewModel.Instance.LocalConfig.HighAlarmStr;
                }
            }
            return result;
        }
        /// <summary>
        /// 更新告警模型
        /// 1.更新持续时间
        /// 2.更新浓度
        /// 3.更新结束时间
        /// </summary>
        /// <param name="oldModel">老模型</param>
        /// <param name="_saveModel">新保存的数据</param>
        /// <param name="isUpgradKeep">是否更新持续时间</param>
        /// <param name="isUpgradPotency">是否更新浓度</param>
        /// <param name="isUpgradEndTime">是否更新结束时间</param>
        /// <returns></returns>
        private Model.ConfigModel.GasMeter.AlarmSearchModel upgradeModel(Model.ConfigModel.GasMeter.AlarmSearchModel oldModel, Model.ConfigModel.GasMeter.GasSaveModel _saveModel, Model.ConfigModel.GasMeter.TaskGasMeterModel _configModel, bool isUpgradKeep, bool isUpgradPotency = false, bool isUpgradEndTime = false)
        {
            List<object> tmpselectkeyList = new List<object>();
            List<object> tmpselectvalueList = new List<object>();
            List<object> tmpinsertkeyList = new List<object>();
            List<object> tmpinsertvalueList = new List<object>();
            if (_configModel.saveAlarmModel == null) _configModel.saveAlarmModel = new Model.ConfigModel.GasMeter.AlarmSearchModel();
            _configModel.saveAlarmModel = oldModel;
            tmpselectkeyList.Clear();
            tmpselectvalueList.Clear();
            tmpinsertkeyList.Clear();
            tmpinsertvalueList.Clear();
            tmpselectkeyList.Add("GasmeterId");
            tmpselectkeyList.Add("RecordIndex");
            tmpselectvalueList.Add(oldModel.GasmeterId);
            tmpselectvalueList.Add(oldModel.RecordIndex);
            //更新持续持续时间
            if (isUpgradKeep)
            {
                _configModel.saveAlarmModel.KeepingTime = compareTime(DateTime.Now, oldModel.StartTime);
                tmpinsertkeyList.Add("KeepingTime");
                tmpinsertvalueList.Add(_configModel.saveAlarmModel.KeepingTime);
            }
            //更新气体浓度
            if (isUpgradPotency)
            {
                if (_configModel.GasType == "O2")
                {
                    if (double.TryParse(_saveModel.GasValue, out alarmPotency) && double.TryParse(_configModel.saveAlarmModel.GasValue, out lastalarmPotency))
                    {
                        //氧气判断是不是大于高警，或者小于低警
                        if ((alarmPotency < _configModel.LowAlarmValue && alarmPotency < lastalarmPotency) || (alarmPotency > _configModel.HighAlarmValue && alarmPotency > lastalarmPotency))
                        {
                            _configModel.saveAlarmModel.GasValue = alarmPotency.ToString("0.0");
                            tmpinsertkeyList.Add("GasValue");
                            tmpinsertvalueList.Add(_configModel.saveAlarmModel.GasValue);
                        }
                    }
                }
                else
                {
                    if (double.TryParse(_saveModel.GasValue, out alarmPotency) && double.TryParse(_configModel.saveAlarmModel.GasValue, out lastalarmPotency))
                    {
                        //高于上一次的值则更新
                        if (alarmPotency > lastalarmPotency)
                        {
                            _configModel.saveAlarmModel.GasValue = alarmPotency.ToString("0.0");
                            tmpinsertkeyList.Add("GasValue");
                            tmpinsertvalueList.Add(_configModel.saveAlarmModel.GasValue);
                        }
                    }
                }
            }
            //更新结束时间
            if (isUpgradEndTime)
            {
                _configModel.saveAlarmModel.EndTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                tmpinsertkeyList.Add("EndTime");
                tmpinsertvalueList.Add(_configModel.saveAlarmModel.EndTime);
            }
            DataBaseHelper.UpDateModel<Model.ConfigModel.GasMeter.AlarmSearchModel>("GasMeterAlarmData", tmpselectkeyList, tmpselectvalueList
                                                                                                                 , tmpinsertkeyList, tmpinsertvalueList);
            if (_configModel.saveAlarmModel == null)
            {
                Console.WriteLine("item is null");
            }
            return _configModel.saveAlarmModel;
        }
        /// <summary>
        /// 插入新的告警记录
        /// </summary>
        /// <param name="_saveModel"></param>
        /// <param name="_configModel"></param>
        private void _insertNewAlarmModel(Model.ConfigModel.GasMeter.GasSaveModel _saveModel, Model.ConfigModel.GasMeter.TaskGasMeterModel _configModel)
        {
            try
            {
                var alarmState = _saveModel.GasState;
                if (MainViewModel.Instance.LocalConfig.IsChangeStateStr == true && MainViewModel.Instance.LocalConfig.HighAlarmStr != "" && MainViewModel.Instance.LocalConfig.LowAlarmStr != "")
                {
                    if (alarmState == "低警")
                    {
                        alarmState = MainViewModel.Instance.LocalConfig.LowAlarmStr;
                    }
                    else if (alarmState == "高警")
                    {
                        alarmState = MainViewModel.Instance.LocalConfig.HighAlarmStr;

                    }
                }
                //插入新纪录
                _configModel.saveAlarmModel = new Model.ConfigModel.GasMeter.AlarmSearchModel()
                {
                    RecordIndex = AlarmTotalCount + 1,
                    AreaName = _configModel.Area,
                    ChildAreaName = _configModel.ChildArea,
                    SettingLocation = _configModel.Postion,
                    GasTestType = _configModel.GasType,
                    GasmeterId = _configModel.SerialNo,
                    GasRange = _configModel.Range,
                    GasUnit = _configModel.Unit,
                    Alarmlimit = _configModel.LowAlarmValue + "|" + _configModel.HighAlarmValue,
                    GasStatu = alarmState,//调用实际的浓度状态，不根据控制器的状态来处理
                    Alarmhigh = _configModel.HighAlarmValue.ToString("0.0"),
                    Alarmlow = _configModel.LowAlarmValue.ToString("0.0"),
                    KeepingTime = "",
                    StartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
                    EndTime = Convert.ToDateTime("0001-01-01 00:00:00"),
                    GasValue = _saveModel.GasState == "故障" ? "0.00" : _saveModel.GasValue,
                };
                if (MainViewModel.Instance.DicGasState.ContainsKey(_configModel.SerialNo))
                {
                    MainViewModel.Instance.DicGasState[_configModel.SerialNo] = _configModel.saveAlarmModel;

                }
                else
                {
                    MainViewModel.Instance.DicGasState.Add(_configModel.SerialNo, _configModel.saveAlarmModel);

                }
                DataBaseHelper.InserOneModel(_configModel.saveAlarmModel, "GasMeterAlarmData");
                ServerTestFcuntion_AddErrorLogEventHandler("探测器-[" + _configModel.saveAlarmModel.GasmeterId + "]-[" + _configModel.saveAlarmModel.GasStatu + "]-浓度[" + _configModel.saveAlarmModel.GasValue + "]", new EventArgs());
                AlarmTotalCount++;
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);

            }

        }
        /// <summary>
        /// 比较时间
        /// </summary>
        /// <param name="endTime"></param>
        /// <param name="startTime"></param>
        /// <returns>返回 时间差 </returns>
        private string compareTime(DateTime endTime, DateTime startTime)
        {
            string result = "";
            try
            {
                TimeSpan ts1 = new TimeSpan(endTime.Ticks);

                TimeSpan ts2 = new TimeSpan(startTime.Ticks);

                TimeSpan ts = ts1.Subtract(ts2).Duration();

                result = ts.Days.ToString() + "天"

                + ts.Hours.ToString() + "小时"

                + ts.Minutes.ToString() + "分钟"

                + ts.Seconds.ToString() + "秒";
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }

            return result;
        }

        #endregion

        public bool ReSpeakFlag { get; set; }
        public bool IsVoiceOpen { get; set; }
        public Queue<string> AlarmMeterList;
        public void LoopSpeckVoice()
        {
            ReSpeakFlag = false;
            IsVoiceOpen = true;
            int loopContinune = int.Parse(MainViewModel.Instance.LocalConfig.VoiceLoopTime);
            try
            {
                while (true)
                {
                    if (MainViewModel.Instance.GasMeterConfig != null)
                    {
                        var alarmModel = AlarmMeterList;
                        if (alarmModel == null || alarmModel.Count == 0 || (IsVoiceOpen == false && MainViewModel.Instance.LocalConfig.IsSpeakForever == false))
                        {
                            VoiceHelper.StopSpeak();
                            Thread.Sleep(1000);
                            continue;
                        }
                        if (VoiceHelper.GetVoiceStatue() == "SRSEIsSpeaking" || VoiceHelper.GetVoiceStatue() == "0")
                        {
                            Thread.Sleep(1000);
                            continue;
                        }
                        while (alarmModel.Count>0)
                        {
                            var tmpModel = alarmModel.Dequeue();

                            var speakWord = tmpModel;
                            VoiceHelper.SpeakChina(speakWord==null?"":speakWord);
                            if (ReSpeakFlag == true)
                            {
                                //VoiceHelper.PauseVoice();
                                break;
                            }
                        }
                    
                            for (int i = 0; i < loopContinune; i++)
                            {
                                Thread.Sleep(1000);
                                //AddLogModel("等待间隔时间过去再继续播报[" + (loopContinune - i).ToString() + "]s");

                            }


                        
                        Thread.Sleep(500);
                        if (ReSpeakFlag == true)
                        {
                            VoiceHelper.StopSpeak();
                            ReSpeakFlag = false;
                            continue;
                        }
                    }
                    Thread.Sleep(1000);
                }
            }
            catch (Exception ex)
            {
                Utility.Helper.PublicHelper.WriteErrorMsg(ex);
            }
        }
        public void TaskRunFunction(List<TaskStartModel> _startParamModels)
        {

            //1.open serial port and create serialPortInstance
            //2.start loop read Data
            //3.for taskModels
            //3-1. for listController
            //3-1-1 build controller instance 
            //3-1-2 instance readData
            //3-1-2-1 check respond is correct
            //3-1-2-1-1 true
            //analyze receive data
            //set respondData 
            //3-1-2-1-2 false
            //if fail time less than settting maxfailtime
            //3-1-2-1-2-1 reload last time Data
            //3-1-2-1-2-2 set respondData is lastData



        }

        private void ShowMsg(string msg, int totalLine, int Controller)
        {
            SetRunStateMsg(totalLine, msg);
            if (totalLine == ViewModel.pageViewModel.MainViewModel.Instance.ShowLogControllerTotalLine && ViewModel.pageViewModel.MainViewModel.Instance.IsShowCommunication && ViewModel.pageViewModel.MainViewModel.Instance.ShowLogControllerAddressIndex == Controller)
            {
                PublicFunctionTool.AddCommuLog(msg, totalLine, Controller);
            }
        }
        private void ShowControlMsg(string msg)
        {

            PublicFunctionTool.AddLog(msg);

        }
    }
}
